#pragma once

#include "../cuCommon/cuTypes.h"
#include "../rtCommon/xobj_string.h"

#include "../FastXML/FastXml.h"
#include <vector>

//////////////////////////////////////////////////////////////////////////
/// Since CUDA is far from OOP I will need basic data containers like 
/// structures below to pass data around and manage it
//////////////////////////////////////////////////////////////////////////
struct S_BaseMaterial
{
	float4 ambient;	
	float4 diffuse;
	float4 specular; 
	float4 emission;

	float  shininess;
};

//////////////////////////////////////////////////////////////////////////
/// C-style functions to work with S_BaseMaterial
//////////////////////////////////////////////////////////////////////////
void						BaseMaterial(S_BaseMaterial  &material);

void						BaseMaterial(S_BaseMaterial	&material, 
														 const float4		&ambient, 
														 const float4		&diffuse, 
														 const float4		&specular, 
														 const float4		&emission, 
														 float					 shininess);

S_BaseMaterial *BaseMaterial(S_BaseMaterial *pMaterial);

S_BaseMaterial *BaseMaterial(S_BaseMaterial *pMaterial, 
														 const float4		&ambient, 
														 const float4		&diffuse, 
														 const float4		&specular, 
														 const float4		&emission, 
														 float					 shininess);


//////////////////////////////////////////////////////////////////////////
/// But for the engine it is much easier to use classes 
//////////////////////////////////////////////////////////////////////////
class C_BaseMaterial : public NVSHARE::FastXmlInterface
{
private:
	S_BaseMaterial m_BaseMaterial;

	static const char *m_Type;

public:

	C_BaseMaterial(void);
	C_BaseMaterial(const float4		&ambient,
								 const float4		&diffuse,
								 const float4		&specular,
								 const float4		&emission,
								 float					 shininess);

	~C_BaseMaterial(void);	

	float4	ambient()		{ return m_BaseMaterial.ambient; }
	float4	diffuse()		{ return m_BaseMaterial.diffuse; }
	float4	specular()	{ return m_BaseMaterial.specular; }
	float4	emission()	{ return m_BaseMaterial.emission; }
	float		shininess() { return m_BaseMaterial.shininess; }

	void		ambient(const float4 & a)		{ m_BaseMaterial.ambient = a; }
	void		diffuse(const float4 & d)		{ m_BaseMaterial.diffuse = d; }
	void		specular(const float4 & s)	{ m_BaseMaterial.specular = s; }
	void		emission(const float4 & e)	{ m_BaseMaterial.emission = e; }
	void		shininess(float sh)					{ m_BaseMaterial.shininess = sh; }

	S_BaseMaterial get();
	
	// return true to continue processing the XML document, false to skip.
	virtual bool processElement(const char	*elementName,					// name of the element
															NxI32        argc,								// number of attributes
															const char **argv,								// list of attributes.
															const char  *elementData,					// element data, null if none
															NxI32        lineno);							// line number in the source XML file

	virtual bool serialize(const char * fileName);
	virtual bool deserialize(const char * fileName);
};